package com.yuanhua.rpc.registry;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

/**
 * @author songguoxiang
 * @version 1.0
 * @description: TODO
 * @date 2022/6/13 8:55
 */
public class RpcRegistry {

    private final int port;
    public RpcRegistry(int port){
        this.port = port;
    }

    public void start(){
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workGroup = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group (bossGroup, workGroup)
                    .channel (NioServerSocketChannel.class)
                    .childHandler (new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline ();
                            // 处理拆包、粘包的编解码器
                            pipeline.addLast (new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
                            pipeline.addLast (new LengthFieldPrepender(4));
                            // 处理序列化的编解码器
                            pipeline.addLast ("encoder", new ObjectEncoder());
                            pipeline.addLast ("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled (null)));
                            // 自己的业务逻辑
                            pipeline.addLast (new MyRegistryHandler());
                        }
                    })
                    .option (ChannelOption.SO_BACKLOG, 128)
                    // 设置长连接
                    .childOption (ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture channelFuture = serverBootstrap.bind (this.port).sync ();
            System.out.println ("RPC Registry start listen at " + this.port);
            channelFuture.channel ().closeFuture ().sync ();
        } catch (Exception e){
            e.printStackTrace ();
        } finally {
            bossGroup.shutdownGracefully ();
            workGroup.shutdownGracefully ();
        }
    }
    public static void main(String [] args) {
        new RpcRegistry(8080).start ();
    }
}
